package com.hnzbxy.api.biz.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hnzbxy.api.biz.converter.DepartmentConverter;
import com.hnzbxy.api.biz.entity.Department;
import com.hnzbxy.api.biz.mapper.DepartmentMapper;
import com.hnzbxy.api.biz.service.DepartmentService;
import com.hnzbxy.api.biz.vo.DepartmentEditVO;
import com.hnzbxy.api.biz.vo.DepartmentVO;
import com.hnzbxy.api.biz.vo.DeptNodeVO;
import com.hnzbxy.api.common.bean.ActiveUser;
import com.hnzbxy.api.system.vo.PageVO;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 部门服务实现类(tk.mybatis版本)
 *
 * @author xiaoge
 * @version 1.0
 * @date 2020/3/7 16:32
 */
@Service
public class DepartmentServiceImpl implements DepartmentService {

    @Autowired
    private DepartmentMapper departmentMapper;

    @Override
    public PageVO<DepartmentVO> findDeptList(Integer pageNum, Integer pageSize, DepartmentVO departmentVO) {
        // 使用PageHelper进行分页
        PageHelper.startPage(pageNum, pageSize);

        // 构建查询条件
        Example example = new Example(Department.class);
        Example.Criteria criteria = example.createCriteria();

        if (departmentVO != null) {
            if (departmentVO.getDeptName() != null && !departmentVO.getDeptName().isEmpty()) {
                criteria.andLike("deptName", "%" + departmentVO.getDeptName() + "%");
            }
            if (departmentVO.getDeptCode() != null && !departmentVO.getDeptCode().isEmpty()) {
                criteria.andLike("deptCode", "%" + departmentVO.getDeptCode() + "%");
            }
            if (departmentVO.getDeptStatus() != null) {
                criteria.andEqualTo("deptStatus", departmentVO.getDeptStatus());
            }
            if (departmentVO.getParentDeptId() != null) {
                criteria.andEqualTo("parentDeptId", departmentVO.getParentDeptId());
            }
        }

        // 设置排序
        example.orderBy("createTime").desc();

        // 执行查询
        List<Department> departments = departmentMapper.selectByExample(example);
        PageInfo<Department> pageInfo = new PageInfo<>(departments);

        // 转换为VO
        List<DepartmentVO> records = departments.stream()
                .map(DepartmentConverter::converterToVO)
                .collect(Collectors.toList());

        return new PageVO<>(pageInfo.getTotal(), records);
    }

    @Override
    public DepartmentVO info(Long id) {
        Department department = departmentMapper.selectByPrimaryKey(id);
        return DepartmentConverter.converterToVO(department);
    }

    @Override
    public List<DeptNodeVO> findDeptTree() {
        // 查询所有部门
        List<Department> departments = departmentMapper.selectAll();
        // 转换为节点列表
        List<DeptNodeVO> nodes = departments.stream()
                .map(DepartmentConverter::converterToNode)
                .collect(Collectors.toList());
        // 构建树形结构
        return buildDeptTree(nodes, 0L);
    }

    /**
     * 构建部门树形结构
     *
     * @param nodes    部门节点列表
     * @param parentId 父节点ID
     * @return 树形结构的部门节点列表
     */
    private List<DeptNodeVO> buildDeptTree(List<DeptNodeVO> nodes, Long parentId) {
        List<DeptNodeVO> result = new ArrayList<>();

        for (DeptNodeVO node : nodes) {
            if (parentId.equals(node.getParentDeptId())) {
                // 递归查找子节点
                List<DeptNodeVO> children = buildDeptTree(nodes, node.getId());
                node.setChildren(children);
                result.add(node);
            }
        }

        return result;
    }

    @Override
    @Transactional
    public void assignParent(Long id, Long parentDeptId) {
        Department department = new Department();
        department.setId(id);
        department.setParentDeptId(parentDeptId);
        // 使用选择性更新，只更新非空字段
        departmentMapper.updateByPrimaryKeySelective(department);
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        // 检查是否有子部门
        Example example = new Example(Department.class);
        example.createCriteria().andEqualTo("parentDeptId", id);
        int count = departmentMapper.selectCountByExample(example);

        if (count > 0) {
            throw new RuntimeException("该部门存在子部门，不能删除");
        }

        departmentMapper.deleteByPrimaryKey(id);
    }

    @Override
    @Transactional
    public void updateStatus(Long id, Integer status) {
        Department department = new Department();
        department.setId(id);
        department.setDeptStatus(status);
        departmentMapper.updateByPrimaryKeySelective(department);
    }

    @Override
    @Transactional
    public void update(Long id, DepartmentEditVO departmentEditVO) {
        Department department = DepartmentConverter.converterToPO(departmentEditVO);
        department.setId(id);
        departmentMapper.updateByPrimaryKeySelective(department);
    }

    @Override
    public DepartmentEditVO edit(Long id) {
        Department department = departmentMapper.selectByPrimaryKey(id);
        return DepartmentConverter.converterToEditVO(department);
    }

    @Override
    @Transactional
    public void add(DepartmentVO departmentVO) {
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        Department department = DepartmentConverter.converterToPO(departmentVO);
        department.setCreatorId(activeUser.getUser().getId());
        departmentMapper.insertSelective(department);
    }

    @Override
    public List<Department> findAll(Long excludeId) {
        Example example = new Example(Department.class);
        Example.Criteria criteria = example.createCriteria();

        if (excludeId != null) {
            criteria.andNotEqualTo("id", excludeId);
        }

        example.orderBy("deptCode").asc();
        return departmentMapper.selectByExample(example);
    }

    @Override
    public List<Department> findAll() {
        Example example = new Example(Department.class);
        example.orderBy("deptCode").asc();
        return departmentMapper.selectByExample(example);
    }
}
    